1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #define _GNU_SOURCE 1 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <poll.h> #include <fcntl.h>
#define BUFFER_SIZE 64
int main(int argc, char* argv[]) { if (argc <= 2) { printf("usage: %s ip_address port_number\n", basename(argv[0])); return 1; } const char* ip = argv[1]; int port = atoi(argv[2]);
struct sockaddr_in server_address; bzero(&server_address, sizeof(server_address)); server_address.sin_family = AF_INET; inet_pton(AF_INET, ip, &server_address.sin_addr); server_address.sin_port = htons(port);
int sockfd = socket(PF_INET, SOCK_STREAM, 0); assert(sockfd >= 0); if (connect(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) { printf("connection failed\n"); close(sockfd); return 1; }
pollfd fds[2]; fds[0].fd = 0; fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = sockfd; fds[1].events = POLLIN | POLLRDHUP; fds[1].revents = 0; char read_buf[BUFFER_SIZE]; int pipefd[2]; int ret = pipe(pipefd); assert(ret != -1);
while (1) { ret = poll(fds, 2, -1); if (ret < 0) { printf("poll failure\n"); break; }
if (fds[1].revents & POLLRDHUP) { printf("server close the connection\n"); break; } else if (fds[1].revents & POLLIN) { memset(read_buf, '\0', BUFFER_SIZE); recv(fds[1].fd, read_buf, BUFFER_SIZE - 1, 0); printf("%s\n", read_buf); }
if (fds[0].revents & POLLIN) { ret = splice(0, NULL, pipefd[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE); ret = splice(pipefd[0], NULL, sockfd, NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE); } }
close(sockfd); return 0; }
|